package com.nj9you.pay.utils;

import java.io.UnsupportedEncodingException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;


public class EncryptUtil {

    /**
     * 字符序列
     */
    static final char[] hexChar = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};

    /**
     * 计算指定字符串的MD5值
     *
     * @param source 字符串
     * @return String MD5值
     */
    public static String getMD5(String source) {
        return getMD5(Utils.getBytes(source));
    }

    /**
     * 计算指定字符串的MD5值
     *
     * @param source 字符串
     * @param update 附加字节
     * @return String MD5值
     */
    public static String getMD5(String source, String update) {
        return getMD5(Utils.getBytes(source), Utils.getBytes(update));
    }

    /**
     * 计算byte数组的MD5值
     *
     * @param source byte数组
     * @return String MD5值
     */
    public static String getMD5(byte[] source) {
        try {
            return hash(source, null, "MD5");
        } catch (NoSuchAlgorithmException e) {
            throw new IllegalStateException(e.getMessage());
        }
    }

    /**
     * 计算byte数组的MD5值
     *
     * @param source byte数组
     * @param update 指定字节数组对摘要最后更新
     * @return String 加密字符串
     */
    public static String getMD5(byte[] source, byte[] update) {
        try {
            return hash(source, update, "MD5");
        } catch (NoSuchAlgorithmException e) {
            throw new IllegalStateException(e.getMessage());
        }
    }

    /**
     * 将字符串根据指定编码进行指定方式（MD5、SHA1、SHA-256、SHA-384、SHA-512）加密
     *
     * @param source   byte数组
     * @param charset  编码
     * @param hashType 编码方式
     * @param update   指定字节数组对摘要最后更新
     * @return String 加密字符串
     * @throws NoSuchAlgorithmException
     * @throws UnsupportedEncodingException
     */
    public static String hash(byte[] source, byte[] update, String hashType) throws NoSuchAlgorithmException {
        MessageDigest md = MessageDigest.getInstance(hashType);
        md.update(source);
        if (update != null) {
            return toHexString(md.digest(update));
        } else {
            return toHexString(md.digest());
        }
    }

    /**
     * 将字节序列转换成文本
     *
     * @param bytes 字节序列
     * @return String 文本
     */
    public static String toHexString(byte[] bytes) {
        StringBuilder sb = new StringBuilder(bytes.length * 2);
        for (int i = 0; i < bytes.length; i++) {
            sb.append(hexChar[(bytes[i] & 0xf0) >>> 4]);
            sb.append(hexChar[bytes[i] & 0x0f]);
        }
        return sb.toString();
    }

}
